<template>
    <div class="page-container">
        <el-backtop :right="100" :bottom="100" ref="refBackTop" :visibility-height="100" target=".el-main"></el-backtop>

        <!-- 头部 -->
        <div class="page-filter">
            <div class="pf-text"><span style="color:red">*</span>角色名称:</div>
            <el-input v-model.trim="objForAdd.name" placeholder="请输入角色名称" clearable />
            <div class="pf-text">描述信息:</div>
            <el-input v-model.trim="objForAdd.desc" placeholder="请输入描述信息" clearable />
            <el-button type="primary" :icon="Plus" @click="handleAddRole" v-permission="'sys:role:create'">添加</el-button>
        </div>
        <!-- 角色列表 -->
        <div class="page-table">
            <el-table :data="roleList" border style="width: 100%" stripe v-loading="loading"
                element-loading-text="拼命加载中...">
                <el-table-column prop="name" label="角色名称" />
                <el-table-column prop="desc" label="说明" />
                <el-table-column label="操作">
                    <template #default="scope">
                        <template v-if="scope.row.name !== '超级管理员'">
                            <el-button type="primary" @click="handleEdit(scope.row)" v-permission="'sys:role:update'">修改</el-button>
                            <el-button type="primary" @click="handleOpenRoleDialog(scope.row)" v-permission="'sys:role:permissionlist'">授权</el-button>
                            <el-button type="danger" @click="handleDelete(scope.row.id)" v-permission="'sys:role:delete'">删除</el-button>
                        </template>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <!-- 分页组件 -->
        <div style="overflow: hidden;">
            <Pagination v-bind="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        </div>
        <!-- 修改对话框 -->
        <el-dialog v-model="dialogVisible" title="修改" width="40%" @close="handleClose">
            <el-form ref="ruleFormRef" :model="objForEdit" :rules="rules" label-width="120px">
                <el-form-item label="角色名称" prop="name">
                    <el-input v-model="objForEdit.name" />
                </el-form-item>
                <el-form-item label="角色描述" prop="desc">
                    <el-input v-model="objForEdit.desc" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="submitForm(ruleFormRef)">
                        确定
                    </el-button>
                    <el-button @click="dialogVisible = false">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
        <!-- 权限配置对话框 -->
        <el-dialog v-model="dialogVisibleRole" title="权限配置" width="40%" style="height: 500px;overflow: hidden;" draggable
            @close="handleCloseRole">
            <el-scrollbar height="300px">
                <el-tree :data="systemPermissions" show-checkbox node-key="id" :expand-on-click-node="false" ref="refElTree"
                    :default-checked-keys="assignedPermissions">
                    <template #default="{ node, data }">
                        <div class="custom-tree-node">
                            <span>{{ node.label }}</span>
                            <span v-if="!data.children">{{ data.id }}</span>
                        </div>
                    </template>
                </el-tree>
            </el-scrollbar>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisibleRole = false">取消</el-button>
                    <el-button type="primary" @click="handleSureCheckRole">
                        确定
                    </el-button>
                </span>
            </template>
        </el-dialog>

    </div>
</template>
<script lang="ts" setup>
import { Goblet, Plus } from '@element-plus/icons-vue';
import { ref, onMounted, reactive, nextTick } from 'vue'
import { post } from '@/utils/http'
import { useUserInfoStore } from '@/stores/userInfo';
import { ElMessage, ElMessageBox, ElTree, ElScrollbar, ElBacktop } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus'
import Pagination from '@/components/pagination/Pagination.vue';
import { ClassPagination } from '#/index'
import { antShaking } from '@/utils/throttling';

//返回顶部节点
const refBackTop = ref()
//显示是否加载
const loading = ref(false)
//添加绑定的对象
const objForAdd = reactive({
    name: '',
    desc: ''
})
//修改绑定的对象
const objForEdit = reactive({
    name: '',
    desc: '',
    status: 0,
    id: 0
})

const ruleFormRef = ref<FormInstance>()
const refElTree = ref()
//验证规则
const rules = reactive<FormRules>({
    name: [
        { required: true, message: '请输入角色名', trigger: 'blur' },
    ]
})
const useUserInfo = useUserInfoStore()
const roleList: TypeRole[] = reactive([])

const pagination: ClassPagination = reactive(new ClassPagination())

//是否显示修改对话框
const dialogVisible = ref(false)
//是否显示权限配置
const dialogVisibleRole = ref(false)

//全部权限
const systemPermissions = ref([])
//当前对象选中的值
const assignedPermissions = ref([])

//被选中的节点数据及id
const checkedKeyObj = reactive({
    roleId: 0,
    permissions: []
})
//所有对象名，用于查询是否同名
const optionsList = ref([])
/**
 * 生命周期mounted请求角色列表
 */
let goAddRole: () => void
onMounted(() => {
    getRoleList()
    goAddRole = antShaking(addRole)
})
/**
 * 请求角色列表数据
 */
function getRoleList() {
    loading.value = true
    const data = {
        _gp: 'admin.role', _mt: 'list', adminId: useUserInfo.userInfo.id,
        page: pagination.currentPage, limit: pagination.pageSize
    }
    post(data).then(res => {
        console.log(res)
        const { data, errmsg, errno } = res
        if (200 === errno && "成功" === errmsg) {
            roleList.length = 0
            roleList.push(...data.items)
            pagination.total = data.total
            nextTick(() => {
                loading.value = false
                refBackTop.value.$el.click?.()
            })
        } else {
            ElMessage.error(errmsg)
        }
    })
}
/**
 * 改变一页多少行,防止多次请求
 * @param value 一页多少行
 */
function handleSizeChange(value: number) {
    let tempCurrent = Math.ceil(pagination.total / value)
    if (tempCurrent < pagination.currentPage) {
        pagination.currentPage = tempCurrent
    }
    pagination.pageSize = value
    getRoleList()
}

/**
 * 改变当前页
 * @param value 当前页数
 */
function handleCurrentChange(value: number) {
    pagination.currentPage = value
    getRoleList()
}
/**
 * 添加角色方法
 */
function addRole() {
    if (objForAdd.name == "") {
        // ElMessage.error('角色名称不能为空')
        ElMessage({
            message: '角色名称不能为空',
            type: 'error',
            duration: 1000
        })
        return
    } else {
        //查询列表中是否有同名的角色名
        const data = { _gp: 'admin.role', _mt: 'options' }
        post(data).then(res => {
            const { errmsg, errno, data } = res
            if (200 === errno) {
                let exits = data.some((items: { label: string; }) => items.label === objForAdd.name)
                if (exits) {
                    ElMessage({
                        message: '角色名称不能相同',
                        type: 'error',
                        duration: 1000
                    })
                    objForAdd.name = ""
                    return Promise.resolve(false)
                } else {
                    return Promise.resolve(true)
                }
            }
        }).then(res => {
            if (res) {
                const data = {
                    _gp: 'admin.role', _mt: 'create',
                    role: JSON.stringify(objForAdd)
                }
                post(data).then(res => {
                    const { data, errmsg, errno } = res
                    if (200 == errno) {
                        ElMessage.success(errmsg)
                    } else {
                        ElMessage.error(errmsg)
                    }
                    //清空文本框，重新加载数据
                    objForAdd.name = ""
                    objForAdd.desc = ""
                    getRoleList()
                })
            }
        })
    }
}
/**
 * 点击添加，防止多次弹出提示框
 */
function handleAddRole() {
    goAddRole()
}
/**
 * 删除角色
 * @param id 角色id
 */
function handleDelete(id: number) {
    ElMessageBox.confirm(
        '是否删除该角色?',
        '警告',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        const data = { _gp: 'admin.role', _mt: 'delete', roleId: id }
        post(data).then(res => {
            const { errno, data, errmsg } = res
            if (data === "ok" && 200 === errno) {
                ElMessage.success('删除成功！！')
                getRoleList()
            } else {
                ElMessage.error(errmsg)
            }
        })
    }).catch(() => {
        ElMessage({
            type: 'info',
            message: '取消成功',
        })
    })
}
/**
 * 修改角色
 * @param row 当前对象
 */
function handleEdit(row: TypeRole) {
    dialogVisible.value = true
    const { id, status, name, desc } = row
    objForEdit.id = id
    objForEdit.status = status
    objForEdit.name = name
    objForEdit.desc = desc
}
/**
 * 确认修改
 */
const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            const data = { _gp: 'admin.role', _mt: 'update', role: JSON.stringify(objForEdit) }
            post(data).then(res => {
                const { errmsg, errno } = res
                if (200 === errno) {
                    getRoleList()
                    dialogVisible.value = false
                    ElMessage.success("修改成功")
                } else {
                    ElMessage.error('修改失败')
                }
            })
        } else {
            console.log('error submit!', fields)
        }
    })
}

/**
 * 关闭修改对话框的回调事件
 */
function handleClose() {
    objForEdit.id = 0
    objForEdit.desc = ""
    objForEdit.name = ""
    objForEdit.status = 0
}

/**
 * 打开权限的对话框
 * @param row 当前行对象
 */
function handleOpenRoleDialog(row: TypeRole) {

    const data = { _gp: "admin.role", _mt: "permissionList", roleId: row.id }
    post(data).then(res => {
        const { data, errmsg, errno } = res
        if (200 === errno) {
            //保存被选中的roleid
            dialogVisibleRole.value = true
            checkedKeyObj.roleId = row.id
            systemPermissions.value = data.systemPermissions
            assignedPermissions.value = data.assignedPermissions
            // refElTree.value.setCheckedKeys(data.assignedPermissions);
        } else {
            ElMessage.error(errmsg)
        }

    })
}
/**
 * 确认授权
 */
function handleSureCheckRole() {
    let checkedList = refElTree.value.getCheckedKeys(true)
    checkedKeyObj.permissions = checkedList
    console.log(checkedKeyObj.permissions)
    const data = { _gp: 'admin.role', _mt: 'permissionSet', roleSetPermissionDTO: JSON.stringify(checkedKeyObj) }
    post(data).then(res => {
        const { data, errmsg, errno } = res
        if (200 === errno) {
            //关闭对话框
            dialogVisibleRole.value = false
            ElMessage.success('授权成功')
            getRoleList()
        } else {
            ElMessage.error(errmsg)
        }
    })
}
/**
 * 关闭权限对话框的回调
 */
function handleCloseRole() {
    // 重置被选数据
    refElTree.value.setCheckedKeys([]);
    checkedKeyObj.permissions = []
    checkedKeyObj.roleId = 0
}

</script>
<style lang="less" scoped>
.page-filter {
    display: flex;
    align-items: center;

    &>.el-input {
        width: 200px;
        margin: 0 10px;
    }

    .pf-text {
        flex-shrink: 0;

    }
}

.custom-tree-node {
    display: flex;
    justify-content: space-between;
    flex: auto;
}

:deep(.el-dialog__footer) {
    position: absolute;
    bottom: 10px;
    right: 10px;
}
</style>